package com.glut.forum.interceptors;

import com.auth0.jwt.exceptions.AlgorithmMismatchException;
import com.auth0.jwt.exceptions.InvalidClaimException;
import com.auth0.jwt.exceptions.SignatureVerificationException;
import com.auth0.jwt.exceptions.TokenExpiredException;
import com.auth0.jwt.interfaces.DecodedJWT;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.glut.forum.common.utils.CheckUtil;
import com.glut.forum.common.utils.JWTUtils;
import lombok.extern.slf4j.Slf4j;
import org.springframework.web.servlet.HandlerInterceptor;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.util.HashMap;
import java.util.Map;

/**
 * @author milo
 * @since 2021/9/2 下午8:04
 * @version 1.0
 */
@Slf4j
public class JWTInterceptor implements HandlerInterceptor {

    @Override
    public boolean preHandle(HttpServletRequest request,
                             HttpServletResponse response,
                             Object handler) throws Exception {

        Map<String, Object> map = new HashMap<>();

        try {
            //获取请求头中的令牌
            String token = request.getHeader("Authorization").split(" ")[1];

            log.info("当前token为：{}", token);
            // token验证
            JWTUtils.verify(token);

            // 将userId添加到request作用域中,由于token具有参数保护的机制
            // 所以token中的userId一般不为空，因为后端在生产token的时候加入了userId,故对userId不做参数验证
            // userCode也一样
            DecodedJWT decodedJWT = JWTUtils.decodeToken(token);

            String uid = decodedJWT.getClaim("userId").asString();

            String ucode = decodedJWT.getClaim("userCode").asString();

            request.setAttribute("uid", uid);
            request.setAttribute("ucode", ucode);

            log.info("当前用户id--{}", uid);
            log.info("当前用户code--{}", ucode);

            return true;
        } catch (SignatureVerificationException e) {

            e.printStackTrace();

            map.put("msg", "签名不一致");
        } catch (TokenExpiredException e) {

            e.printStackTrace();

            map.put("msg", "令牌过期");
        } catch (AlgorithmMismatchException e) {

            e.printStackTrace();

            map.put("msg", "算法不匹配");
        } catch (InvalidClaimException e) {

            e.printStackTrace();

            map.put("msg", "失效的payload");
        } catch (Exception e) {

            e.printStackTrace();

            map.put("msg", "token无效");
        }

        map.put("state", false);

        //响应到前台: 将map转为json
        String json = new ObjectMapper().writeValueAsString(map);

        response.setContentType("application/json;charset=UTF-8");

        response.getWriter().println(json);

        return false;
    }
}
